<template>
  <div class="hello"></div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

let renderer,
  camera,
  scene,
  objects = [];

import { GUI } from "dat.gui";
const gui = new GUI();
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  created() {
    this.main();
    this.setScene();
    this.setCamera();
    this.setLight();
    this.setObjts();
    this.renderThree();
    this.orthers();
  },
  methods: {
    main() {
      renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      // add the output of the render function to the HTML
      document.body.appendChild(renderer.domElement);
    },
    setScene() {
      scene = new THREE.Scene();
      // scene.background = new THREE.Color("#eee");
    },
    setCamera() {
      /**
       * dat
       */
      let guiControls = {
        sx: 0,
        sy: 0,
        sz: 10,
        near: 0.01,
        far: 1000,
      };

      camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        guiControls.near,
        guiControls.far
      );
      camera.position.set(0, 10, 10);
      camera.lookAt(50, 50, 50);
      console.log(camera.up);

      // const cameraHelper = new THREE.CameraHelper(camera);
      // cameraHelper.visible = true;
      // scene.add(cameraHelper);

      const folder = gui.addFolder("相机设置");
      folder
        .add(guiControls, "sx", -100, 100, 1)
        .name("相机x:")
        .onChange((e) => {
          camera.position.set(e, 0, 10);
        });
      folder
        .add(guiControls, "sy", -100, 100, 1)
        .name("相机y:")
        .onChange((e) => {
          camera.position.set(0, e, 10);
        });
      folder
        .add(guiControls, "sz", -100, 100, 1)
        .name("相机z:")
        .onChange((e) => {
          camera.position.set(0, 0, e);
        });
      folder
        .add(guiControls, "near", 0.1, 1000, 0.1)
        .name("相机near:")
        .onChange((e) => {
          camera.near = e;
          camera.updateProjectionMatrix();
          console.log(camera.updateProjectionMatrix);
        });
      folder
        .add(guiControls, "far", 1, 10000, 10)
        .name("相机far:")
        .onChange((e) => {
          camera.far = e;
          camera.updateProjectionMatrix();
        });
    },
    setLight() {
      {
        const light = new THREE.AmbientLight(0xffffff); // soft white light
        light.position.set(0, 0, 0);
        scene.add(light);
        /**
         * dat
         */
        let guiControls = {
          lx: 0,
          ly: 0,
          lz: 10,
          lcolor: "#fff",
          intensity: 1,
        };
        const folder = gui.addFolder("灯光设置");
        folder
          .add(guiControls, "lx", -100, 100, 1)
          .name("灯光x:")
          .onChange((e) => {
            light.position.set(e, 0, 10);
          });
        folder
          .add(guiControls, "ly", -100, 100, 1)
          .name("灯光y:")
          .onChange((e) => {
            light.position.set(0, e, 10);
          });
        folder
          .add(guiControls, "lz", -100, 100, 1)
          .name("灯光z:")
          .onChange((e) => {
            light.position.set(0, 0, e);
          });
        folder
          .addColor(guiControls, "lcolor")
          .name("灯光颜色:")
          .onChange((e) => {
            light.color = new THREE.Color(e);
          });
        folder.add(light, "intensity", 0, 2, 0.01);
      }
    },
    async setObjts() {
      // 创建几何体
      const homeObj = new THREE.Object3D();
      homeObj.name = "homeObj";
      homeObj.position.set(0, 0, 0);
      scene.add(homeObj);
      objects.push(homeObj);

      // const geometry = new THREE.CylinderGeometry(1, 1.5, 1, 80);
      // const material = new THREE.MeshPhongMaterial({
      // 	// color: 0xffff00,
      // 	// emissive: 0xffff00,
      // });
      // const mesh = new THREE.Mesh(geometry, material);
      // homeObj.add(mesh);

      const figureObj = new THREE.Object3D();
      figureObj.name = "figureObj";
      homeObj.add(figureObj);
      objects.push(figureObj);

      // const gltf = await this.loadFile("/static/3d/koala_con_flor/scene.gltf");
      // gltf.scene.scale.set(3, 3, 3);

      const gltf = await this.loadFile(
        "/static/3d/blender_collab_15.0_final_scene/scene.gltf"
      );
      /**
       * 显示不出来是因为大小原因
       */
      // gltf.scene.scale.set(0.003766, 0.003766, 0.003766);
      figureObj.add(gltf.scene);
      // figureObj.position.set(0, 0, 10);
      // figureObj.scale.set(0.01, 0.01, 0.01);
      this.setTextrue();
      /**
       * dat
       */
      let guiControls = {
        scale: 0.1,
      };
      const folder = gui.addFolder("模型设置");
      folder
        .add(guiControls, "scale", 0.00001, 0.01, 0.000001)
        .name("模型缩放:")
        .onChange((e) => {
          gltf.scene.scale.set(e, e, e);

          // figureObj.scale.set(e, e, e);
        });

      const axesHelper = new THREE.AxesHelper(2);
      figureObj.add(axesHelper);
    },
    renderThree() {
      function resizeRendererToDisplaySize(renderer) {
        const canvas = renderer.domElement;
        const width = canvas.clientWidth;
        const height = canvas.clientHeight;
        const needResize = canvas.width !== width || canvas.height !== height;
        if (needResize) {
          renderer.setSize(width, height, false);
        }
        return needResize;
      }
      function render() {
        if (resizeRendererToDisplaySize(renderer)) {
          const canvas = renderer.domElement;
          camera.aspect = canvas.clientWidth / canvas.clientHeight;
          camera.updateProjectionMatrix();
        }
        // objects.forEach((item) => {
        //   //   console.log(item);
        //   if (item.name == "figureObj") {
        //     item.rotation.y = time;
        //   }
        // });
        renderer.render(scene, camera);
        requestAnimationFrame(render);
      }
      requestAnimationFrame(render);
    },
    orthers() {
      const controls = new OrbitControls(camera, renderer.domElement);
      // controls.minPolarAngle = 0.5 * Math.PI;
      controls.maxPolarAngle = (0.9 * Math.PI) / 2;
      controls.enableZoom = true;
    },
    //加载模型
    loadFile(url) {
      const loader = new GLTFLoader(); //引入模型的loader实例
      return new Promise((resolve, reject) => {
        loader.load(
          url,
          (gltf) => {
            console.log("模型", gltf);
            resolve(gltf);
          },
          ({ loaded, total }) => {
            // let load = Math.abs((loaded / total) * 100);
            // this.loadingWidth.value = load;
            // if (load >= 100) {
            //   setTimeout(() => {
            //     this.isLoading.value = false;
            //   }, 1000);
            // }
            console.log((loaded / total) * 100 + "% loaded");
          },
          (err) => {
            reject(err);
          }
        );
      });
    },
    /**
     * 设置贴图、颜色
     */
    setTextrue() {
      const textrueGender = (url) => {
        return new THREE.TextureLoader().load(
          // 由于当前使用的都是本地的贴图所以我们设置成本地的路径
          "/static/3d/blender_collab_15.0_final_scene/textures/" + url
        );
      };
      let texture = {
        Plane_6: {
          zurl: "chelun.jpg",
        },
        hood_21: {
          zcolor: "red",
        },
      };

      scene.traverse((child) => {
        if (child.isMesh) {
          console.log(child.name);
          for (const key in texture) {
            const itemInfo = texture[key];
            if (key == child.name && itemInfo.zurl) {
              // 设置贴图
              child.material.map = textrueGender(itemInfo.zurl);
            }
            if (key == child.name && itemInfo.zcolor) {
              // 设置颜色
              child.material.color.set(itemInfo.zcolor);
            }
          }
        }
      });
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
